import datetime
from dataclasses import dataclass, field
from typing import Self  # type: ignore

from src.application.order.enums import OrderPeriod, OrderStatus, OrderType
from src.domain.common.constants import Empty
from src.domain.common.entities import AggregateRoot
from src.domain.order.entities.allowed_ip import AllowedIpEntity
from src.domain.order.entities.proxy import ProxyEntity
from src.domain.order.value_objects.order_id import OrderId
from src.domain.user.value_objects import UserId


@dataclass
class OrderAggregate(AggregateRoot):
    """
    Полная модель заказа
    """

    buyer_id: UserId
    summ: float
    summ_total: float
    order_type: OrderType
    category_id: int
    period: OrderPeriod
    proxies: list[ProxyEntity]
    country_id: int
    provider_id: int
    id: OrderId | None = None
    status: OrderStatus = OrderStatus.active
    site_id: int | None = None
    vpn_server_id: int | None = None
    allowed_ips: list[AllowedIpEntity] = None
    auto_renew: bool = field(default=False)
    expiring_on: datetime.datetime | None = None
    was_renewed: datetime.datetime | None = None
    last_notified: datetime.datetime | None = None

    @classmethod
    def create_order(
        cls,
        *,
        buyer_id: UserId,
        order_summ: float,
        order_summ_total: float,
        order_type: OrderType,
        category_id: int,
        period: OrderPeriod,
        proxies: list[ProxyEntity],
        country_id: int,
        provider_id: int,
        site_id: int | None,
        vpn_server_id: int | None = None,
        expiring_on: datetime.datetime | None = None,
    ) -> Self:
        """
        Создание модели заказа
        """
        user = OrderAggregate(
            buyer_id=buyer_id,
            order_type=order_type,
            order_summ=order_summ,
            order_summ_total=order_summ_total,
            category_id=category_id,
            period=period,
            proxies=proxies,
            country_id=country_id,
            provider_id=provider_id,
            site_id=site_id,
            vpn_server_id=vpn_server_id,
            expiring_on=expiring_on,
        )

        return user

    def update(
        self,
        *,
        first_name: str | Empty = Empty.UNSET,
        last_name: str | Empty = Empty.UNSET,
    ) -> None:
        """
        Обновление информации, пользователя
        """
        self._check_on_delete()

        if not first_name == Empty.UNSET:
            self.first_name = first_name
        if not last_name == Empty.UNSET:
            self.last_name = last_name

    def update_status(self, status: OrderStatus):
        """Меняем статус заказа"""
        self.status = status

    def clear_proxies(self):
        """Удаляем прокси из заказа"""
        self.proxies.clear()

    def clear_allowed_ips(self):
        """Удаляем разрешенные ip из заказа"""

        self.allowed_ips.clear()

    def add_allowed_ip(self, allowed_ip: AllowedIpEntity):
        """Добавляем разрешенный ip"""

        self.allowed_ips.append(allowed_ip)

    def update_expiring(self, expiring_on: datetime.datetime, was_renewed: datetime.datetime):
        """Обновляем срок действия заказа"""

        self.expiring_on = expiring_on
        self.was_renewed = was_renewed

    def set_autorenew(self, autorenew: bool):
        """Включаем/выключаем автообновление"""

        self.auto_renew = autorenew

    def set_avatar(self, avatar_path: str | None) -> None:
        """
        Установка аватара
        """
        if avatar_path:
            self.avatar_path = avatar_path
